home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Environments / Prograph Classic 2.6.1 / Prograph Tutorial Manual / Prograph Tutorial / Prograph Tutorial.rsrc / TEXT_159.txt < prev    next >
Encoding:
Text File  |  1995-10-16  |  16.0 KB  |  346 lines

  1.  Chapter 7
  2.  Language Basics:     Methods
  3.  t Method Cases for Conditional Execution
  4.  t Local Methods for Design Organization
  5.  t Local Methods for Conditional Execution
  6.  t List Multiplexes
  7.  t Loop Multiplexes
  8.  t List and Loop Annotations Together:     Mixed 
  9.           Multiplexes
  10.  t Finish and Terminate Controls
  11.  t The Fail Control
  12.  t Check Your Progress
  13.  
  14. The objective of this chapter‚Äôs tutorial is to explore the design and development of methods. Methods are the process side of Prograph. The essential power of Prograph comes from its marriage of the dataflow model of process description with the conceptual clarity and flexibility of class-based object orientation.
  15.  
  16. In the previous tutorial, you developed knowledge and skills in creating structure within a Prograph environment to implement an application design. The goal of this tutorial is for you to learn how to make the objects you can now create behave any way you wish. To that end, you explore method*714* case structure, including the use of multicase local methods as a means of conditional execution of subtasks. List, loop, and mixed multiplexes, both on method and primitive operations, are also covered.
  17.  
  18. Prograph has an enormously rich set of control and multiplex annotations. This tutorial presents only a subset of these features and demonstrates their capabilities. Some additional annotations find their way into other tutorial exercises. But exploring some of these features is left up to you. 
  19.  
  20. The Reference*935* manual provides information on all the capabilities of Prograph. As you begin to tackle your own applications, if you think Prograph should be able to do something, it probably can. Check the Reference manual and look at the many example files for solutions beyond those presented here.
  21.  
  22. t    Method Cases for Conditional Execution
  23.  
  24. *188*The most basic Prograph method is one that simply ‚Äúdoes its thing‚Äù when called, always doing the same thing under any and all circumstances. Many of the methods you have developed so far have been of this simple type. But circumstances often require varying responses to varying conditions.
  25.  
  26. Most programming languages provide a means of*354* conditional execution. Prograph is no exception. In text-based languages, a particular syntax is used to structure such variations in program flow. Typical grammatical constructions for conditional execution are:*429**430**1160*
  27.  
  28. IF <condition> THEN <response> END
  29.  
  30. or
  31.  
  32. IF <condition> THEN <trueResponse> ELSE <falseResponse> END
  33.  
  34. or
  35.  
  36. WHILE <condition> DO <this> END
  37.  
  38. or*147*
  39.  
  40. CASE <selectorLabel> OF
  41.  <label1> : <response1> ;
  42.  <label2> : <response2> ;
  43.  <label3> : <response3> ;
  44. END
  45.  
  46. While an initial comparison would suggest that Prograph‚Äôs*139* case structure most closely resembles the case statement above, Prograph actually combines the functionality of all these forms in its case structure, control annotations, and*563* *790**797*Match operation features. As you become increasingly familiar with the various combinations of Prograph conditional controls, you could reasonably conclude that Prograph provides among the most complete and flexible conditional-execution models implemented in a programming language to date.
  47.  
  48. *756*The most basic Prograph conditional execution form is the*213* Next Case annotation*590* with a*651* Match operation or a conditional test based on one or more of the available boolean primitives. Next Case annotation has two forms.*753* Next Case on Failure:
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65. and*755* Next Case on Success:
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82. The*200* control annotations are the small square boxes to the right of the Match operations which are looking for an input string, "Grapefruit", to decide whether to complete the case or proceed to the next case.
  83.  
  84. The Next Case on Failure annotation has an 5 in the Next Case box.
  85.  
  86.  
  87.  
  88. Attached to a boolean operation, a*754* Next Case on Failure means, ‚ÄúIf this test fails, go to the next case.‚Äù Attached to a Match operation, a Next Case on Failure means, ‚ÄúIf the value coming into this Match operation is not equal to the constant value of this operation, go to the next case.‚Äù 
  89.  
  90. The Next Case on Success annotation has a 3 in the Next Case box.
  91.  
  92.  
  93.  
  94. Attached to a boolean operation, a Next Case on Success means, ‚ÄúIf this test succeeds, go to the next case.‚Äù Attached to a*564* *652*Match operation, a Next Case on Success means, ‚ÄúIf the value coming into this Match operation is equal to the constant value of this operation, go to the next case.‚Äù 
  95.  
  96. In the simplest form, a method using Next Case and having two cases is like an IF <matchTest> THEN <case1> ELSE <case2> expression. The most concise <matchTest> form is one using the*798* Match operation.
  97.  
  98. The Match operation is a shorthand notation equivalent to an expression using the boolean primitive*834* = *7*with the Match value‚Äôs constant as the right input to the = primitive:
  99. ¬†                                                                               
  100.  
  101.  
  102.  
  103.          is equivalent to
  104.  
  105.  
  106.  
  107.  
  108.  
  109. In either form above, if the input value is equal to ten, the test succeeds and execution of the method continues in the current case. If the input value is anything other than ten, the test fails and Prograph immediately stops execution of the current case and begins executing the next case.
  110.  
  111. When more than two cases are involved, the equivalent grammatical construction is similar to an IF‚ĶTHEN‚ĶELSEIF‚ĶELSEIF‚ĶELSE‚ĶEND or to a CASE OF‚ĶEND expression in text-based programming languages.
  112.  
  113. Let‚Äôs now explore multiple cases. Develop a method which, given a month name as input, tells how many days are in the month‚Äîa Prograph implementation of ‚Äú30 days has September, April, June and November; all the rest have 31, except for February, which has 28.‚Äù (Forget about leap years for the time being.)
  114.  
  115. u    Start Prograph and create a universal method, month query, to feed the user‚Äôs response into a days in month method as follows:
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128. u    Double-click the left side of the days in month operation to create the new universal method and open its first case window. This conditional execution decision tests whether the input month name is found in the list of month names for months with 30 days. Construct your first case of days in month to look like this:
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143. The conditional test is a Next Case on Success. The (in) operation returns zero if it does not find the required input item in the left input list (here, if the month name is not in the 30 days list). So, a Next Case on Success test signals a drop to the next case when it succeeds in not finding a value.
  144.  
  145. u    Option-click the right*127* case arrow in the title bar of the days in month method to simultaneously create and open a second case of this method. As a reminder, these are your*133* case controls:
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156. u    Taking your design cues from the reminder rhyme, ‚ÄúAll the rest have 31‚Ķ,‚Äù make case two jump to its conclusion without a conditional test.
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165. Of course this neglects the condition in the rhyme‚Äôs third line with regard to February. Though the rhyme‚Äôs conditional ordering serves well as a mnemonic device, it is a bad model for direct computer implementation. Case two implements the gross assumption ‚Äúall the rest have 31‚Äù unconditionally, so adding the ‚Äúexcept February‚Äù clause as case three is nonproductive. Case three never executes.
  166.  
  167. Your implementation, then, must put the February-exception case ahead of the ‚Äú31-days-assumption‚Äù case. Prograph‚Äôs *145*Case List pane makes this kind of case modification easy.
  168.  
  169. u    Click the Case List button to open the Case List pane along the bottom of the days in month 2:2 window. Position the crosshair cursor between the first and second case icons in the*130* Case List pane and Command-click to create a new case.
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180. The title of the active case window has changed to days in month 3:3, indicating the case has been ‚Äúbumped down the line‚Äù by your creation of a new second case.
  181.  
  182. u    Double-click the second case icon in the Case List pane to open its case window. Use a Match operation with a February string constant to check for the except-February condition.
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194. Note that here the test is a Next Case on Failure as the Match is looking for a particular string and fails if it does not find it. 
  195.  
  196. u    Command-click the close box to collectively close all three cases of days in month. Open the Stack window and execute month query several times. Enter a different month name each time you execute the query and observe the case executions in the Stack window. (Use some Step/Show or Breakpoint settings to get a better look at how days in month cases are executed.)
  197.  
  198. Observing the executions of the cases of days in month in the Stack window and reflecting on the configuration of the current implementation, two things become clear.
  199.  
  200. o    Of the 12 possible answers, 7 are responded to by the third case, making for an inefficient conditional decision process.
  201.  
  202. o Non-month name inputs are responded to as having 31 days.
  203.  
  204. Let‚Äôs add a design enhancement to address these weaknesses as follows:
  205.  
  206. u    Open days in month and open its Case List pane. To make the third case the first, simply drag the third icon in the Case List pane to the left and release the mouse button when the ghost rectangle you are dragging is over or slightly to the left of the first case icon. This case shuffle is reflected in the title bar of the window, which shows that what was the first case, 1:3, has become the second case, 2:3.
  207.  
  208. u    Double-click the first case icon and edit its case. Provide a conditional test to check for the input name in the list of the seven month names for months having 31 days. (You can use a cut, paste, and edit of the conditional test operations from the second case to make quick work of this modification.)
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224. u    Add a fourth case that passes the string "Sorry, this is not a month name. Try again." to the output bar to provide an error-catching condition for unrecognized input.
  225.  
  226. Now rerun month query a few times with the Stack window open and notice the difference. Nearly 60 percent of the acceptable month names are responded to by the first case. Typos and other entry errors get a reasonable response. 
  227.  
  228. The overall design of cases for days in month has been improved. The flexible editing features of the*146**131* Case List pane let you develop and modify a method‚Äôs case structure quickly and easily. In addition to the click to create and drag to reorder features, you can cut, copy, paste, and replicate cases in the Case List pane. And any of these actions can be performed on multiply selected icons within the Case List pane.
  229.  
  230. In addition to direct icon manipulations in the Case List pane, a number of keyboard-plus-case-arrow click routines provide shortcuts for creating, opening and closing cases within a method. Refer to the Reference *936* manual for additional information on the Option-click, Shift-click, and Command-click features of the case arrows. (Or simply experiment here with days in month to determine how these keyboard modifiers affect clicks on the case arrows.)
  231.  
  232. t    Local Methods for Design Organization
  233.  
  234. *256**530*Local methods serve a variety of purposes. Perhaps the most basic is design organization and ‚Äúhousecleaning.‚Äù A complex method can suffer a condition called ‚Äúdatalink spaghetti.‚Äù *1091*As a method becomes more complex, it can become increasingly difficult to determine what the method is doing and what connections datalinks are making. Local methods*532* can solve this problem by providing logical organization and clearing out the datalink confusion.
  235.  
  236. There is a chicken-and-egg aspect to local methods. You can work top-down, laying in your high-level local operation nodes in a case window, or you can use the*655* Opers to Local*801**809* facility to encapsulate a collection of logically related operations within a method‚Äôs case that is growing too complex. Reconsider the Folks Database example you developed in the Grand Tour. You can find a nonlocalized version of this mini-application in your Tutorial Examples Δí .
  237.  
  238. u    Save your current work to disk so you can return to it after this example. Then open the Spaghetti Folks DB file in the Ch 7 Δí folder.
  239.  
  240. u    Open and inspect the Person/Add method:
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267. As you can see, the nonlocalized version of Add is getting out of hand:  you have to scroll vertically or significantly enlarge its window to see every operation that takes place when a Person is added to the People database. There is little room for explanatory comments. And the relationship of the operations to each other is lost in the*257* crisscrossing paths of datalinks. 
  268.  
  269. Such complex methods are difficult to maintain, as you can quickly forget what is flowing where, even after only a few days away from working on your application. The task can be even worse if someone other than the original author is attempting to maintain or extend this application.
  270.  
  271. You can clean up this method and provide logical order to it by refreshing your skills in using the Opers to Local feature of the Prograph editor. The higher-level tasks that this collection of operations performs are:
  272.  
  273. o    make a new Person
  274.  
  275. o    add Person to database
  276.  
  277. o    update the window.
  278.  
  279. By nesting the operations performing each of these tasks into a local, what is going on in your code becomes obvious to anyone who inspects your application.
  280.  
  281. u    Start by isolating the operations that create the new Person object whose name is entered in the Folks Database window. Drag a selection rectangle enclosing the operations in the top half of the case window. Your collection of selected operations should look like this before you capture them in a local.
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298. u    Select Opers to Local from the Opers menu. Type make a new Person as the name of the newly created local operation. Next drag a selection rectangle around the two People persistents and the attach-r operation, and then select Opers to Local. Type add Person to database to name this local.
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322. u    Capture the remaining operations in a local and type update the window to name it. Drag the locals around to get a clean and organized appearance. This once unwieldy collection of operations is now represented by this high-level case diagram.
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335. __________________________________________________________
  336. NOTE:  Depending on the exact arrangement of the operations that you ‚Äúcapture‚Äù in a local as above, you may occasionally get some crisscrossing in your datalinks. This is due to the topographical algorithm that computes the necessary roots and terminals for the local and makes all the right connections to the new local‚Äôs encapsulated operations.
  337.  
  338. Once you have captured and cleaned up your top-level case diagram, you may occasionally want to manually override the editor‚Äôs connections. In the above example, your update the window local may have resulted in a crossed input to the left and right terminals. For the clean appearance as shown above, you can simply rewire the datalinks. All links to the left can be switched to the right and those on the right can go to the left, for example.
  339.  
  340. Such rearrangement is a matter of taste and situation. If you are the sole author of an application, it might not matter if occasional crossed datalinks occur. If you are a member of a team, on a large-scale corporate project for example, you might want to clean up parts of your case diagrams to improve their appearance when they are printed out for documentation purposes. Also, cleaner diagrams can be more easily maintained by others over time.
  341.  
  342. The important point is that the Prograph editor does a correct job for you automatically with regard to capturing operations into local methods. Your aesthetics and sensibilities may, however, be more critical than its algorithms.
  343. -----------------------------------------------------------
  344.  
  345. The transformed method is now more self-documenting. It is apparent that three tasks are performed when the Add button is pushed. Further, the data and object-flow dependencies among the subtasks have become obvious. Compare the insights you can gain from inspecting this case diagram from the original nonlocalized version. Clearly, local methods can contribute much to logically organizing your methods.
  346.